using System;
using System.Xml;
using DesignByContract;
using Outcoding.GraphGenerator.Entities;
using Outcoding.GraphGenerator.Util.Logging;

namespace Outcoding.GraphGenerator.Composition{
    public class ValueAxisBuilder : BuilderBase{
        #region Attributes

        private string currencyAttr = "currency";
        private string decimalPlacesAttr = "decimal-places";
        private string fontColorAttr = "font-color";
        private string fontDecorationAttr = "font-decoration";
        //font attributes
        private string fontNameAttr = "font-name";
        private string fontSizeAttr = "font-size";
        private string thousandsSeparatorAttr = "thousands-separator";
        private string useNegativesAttr = "use-negatives";
        private string usePercentAttr = "use-percent";

        #endregion

        private readonly string mNodeName = XmlTagNames.valueaxis.ToString();

        private XmlNode mNode;

        private string mNodePath{
            get { return "./" + mNodeName; }
        }

        public override void SelectNode(XmlDocument document){
            throw new NotImplementedException("The method or operation is not implemented.");
        }

        public override void Compose(){
            throw new NotImplementedException("The method or operation is not implemented.");
        }

        public override void Compose(XmlNode node){
            mNode = node.SelectSingleNode(mNodePath);
            try{
                BuildObject(mNode);
            }
            catch (PreconditionException preExc){
                LogManager.Instance.LogWarning("ValueAxis entity could not be created; process aborted.", preExc);
            }
        }

        public override void AppendToParent(object parent){
            Check.Require(parent is Axes, "Parent object not a valid argument");
            (parent as Axes).ValueAxis = (ValueAxis) mProduct;
        }

        private void BuildObject(XmlNode axesXmlNode){
            var valueAxis = new ValueAxis();

            if (axesXmlNode.Attributes[decimalPlacesAttr] != null)
                valueAxis.DecimalSpaces = ParseDecimalPlacesAttribute(axesXmlNode);
            if (axesXmlNode.Attributes[useNegativesAttr] != null)
                valueAxis.HasNegativePrefix = ParseUseNegativesAttribute(axesXmlNode);
            if (axesXmlNode.Attributes[usePercentAttr] != null)
                valueAxis.HasPercentSufix = ParseUsePercentAttribute(axesXmlNode);
            if (axesXmlNode.Attributes[currencyAttr] != null){
                valueAxis.CurrencyString = ParseCurrencyAttribute(axesXmlNode);
                //in case both currency and percent appears, currency will be used
                valueAxis.HasPercentSufix = false;
            }
            if (axesXmlNode.Attributes[thousandsSeparatorAttr] != null)
                valueAxis.ThousandsSeparator = ParseThousandsAttribute(axesXmlNode);
            //font attributes
            if (axesXmlNode.Attributes[fontNameAttr] != null)
                valueAxis.FontName = ParseFontNameAttribute(axesXmlNode);
            if (axesXmlNode.Attributes[fontSizeAttr] != null)
                valueAxis.FontSize = ParseFontSizeAttribute(axesXmlNode);
            if (axesXmlNode.Attributes[fontDecorationAttr] != null){
                valueAxis.IsFontBold = ParseIsFontBoldAttribute(axesXmlNode);
                valueAxis.IsFontItalic = ParseIsFontItalicAttribute(axesXmlNode);
                valueAxis.IsFontUnderline = ParseIsFontUnderlineAttribute(axesXmlNode);
            }
            if (axesXmlNode.Attributes[fontColorAttr] != null)
                valueAxis.Color = ParseColorAttribute(axesXmlNode);
            mProduct = valueAxis;
        }

        public string ParseCurrencyAttribute(XmlNode axesXmlNode){
            return axesXmlNode.Attributes[currencyAttr].Value;
        }

        public string ParseDecimalPlacesAttribute(XmlNode axesXmlNode){
            return axesXmlNode.Attributes[decimalPlacesAttr].Value;
        }

        public bool ParseUseNegativesAttribute(XmlNode axesXmlNode){
            return Boolean.Parse(axesXmlNode.Attributes[useNegativesAttr].Value);
        }

        public bool ParseUsePercentAttribute(XmlNode axesXmlNode){
            return Boolean.Parse(axesXmlNode.Attributes[usePercentAttr].Value);
        }

        public string ParseThousandsAttribute(XmlNode axesXmlNode){
            return axesXmlNode.Attributes[thousandsSeparatorAttr].Value;
        }

        private string ParseFontNameAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontNameAttr] != null, "font-name attribute not present");
            return axesXmlNode.Attributes[fontNameAttr].Value;
        }

        private int ParseFontSizeAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontSizeAttr] != null, "font-size attribute not present");
            return Int32.Parse(axesXmlNode.Attributes[fontSizeAttr].Value);
        }

        private bool ParseIsFontBoldAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontDecorationAttr] != null, "font-decoration attribute not present");
            return axesXmlNode.Attributes[fontDecorationAttr].Value.Contains("bold");
        }

        private bool ParseIsFontItalicAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontDecorationAttr] != null, "font-decoration attribute not present");
            return axesXmlNode.Attributes[fontDecorationAttr].Value.Contains("italic");
        }

        private bool ParseIsFontUnderlineAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontDecorationAttr] != null, "font-decoration attribute not present");
            return axesXmlNode.Attributes[fontDecorationAttr].Value.Contains("underline");
        }

        private long ParseColorAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontColorAttr] != null, "color attribute not present");

            return Entities.Util.ColorTranslation(axesXmlNode.Attributes[fontColorAttr].Value);
        }
    }
}